﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using DataAssociations.Repository.Connection.RDBMSConnectionInterfaces;
using DataAssociations.Repository.Connection.RDBMSSchemaExplorer;
using DataAssociations.Repository.Connection.RDBMSSchemaExplorer.Interfaces;
using DataAssociations.Repository.Connection.ValidationRules;
using DataAssociations.Repository.Queries;

namespace DataAssociations.ConnectionOptionPartials
{
    public class BaseUserControl : UserControl
    {
        private readonly Dictionary<Type, Func<string, string>> _interfaceMembersNamesConstructor
            = new Dictionary<Type, Func<string, string>>
                  {
                      {typeof (string), x => { return "textBox" + x; }},
                      {typeof (bool), x => { return "checkBox" + x; }},
                      {typeof (int?), x => { return "textBox" + x; }},
                  };

        protected IConnectionStringType Model;
        public Dictionary<string, string> ValidationErrorsDictionary = new Dictionary<string, string>();

        public IConnectionStringType GetConnection()
        {
            return Model;
        }

        public IRelationalSchemaExplorer GetSchemaExporter()
        {
            return Model.GetSchemaExporter;
        }

        public IDataRepository GetDataRepository()
        {
            return Model.GetDataRepository;
        }

        public bool FillAndValidateForm()
        {
            ValidationErrorsDictionary.Clear();
            foreach (var property in Model.GetType().GetProperties().Where(x => x.GetSetMethod() != null))
            {
                var interfaceObjectName = _interfaceMembersNamesConstructor[property.PropertyType](property.Name);
                Control control = Controls.Find(interfaceObjectName, true).Single();

                object[] metadataAttributes = property.GetCustomAttributes(typeof(AbstractValidationAttribute), true);
                if (metadataAttributes.Length > 0)
                {
                    foreach (var metadataAttribute in metadataAttributes)
                    {
                        if (!((AbstractValidationAttribute)metadataAttribute)
                                 .IsValid(control.Text))
                        {
                            ValidationErrorsDictionary.Add(property.Name,
                                                           ((AbstractValidationAttribute)metadataAttribute).
                                                               ValidationStringError);
                        }
                    }
                    if (ValidationErrorsDictionary.Where(x => x.Key == property.Name).Count() == 0)
                    {
                        SetValue(property, control.Text);
                    }

                }
                else
                {
                    SetValue(property, control.Text);
                }
            }
            return ValidationErrorsDictionary.Count == 0;
        }

        private void SetValue(System.Reflection.PropertyInfo property, string data)
        {
            Type propertyType = property.PropertyType;

            try
            {
                var convertedData = Convert.ChangeType(data, propertyType);
                property.SetValue(Model, convertedData, null);
            }
            catch
            {}
        }
    }
}
